//
//  AFNetworkUtils.m
//  MSHD
//
//  Created by HCreater on 2017/12/2.
//  Copyright © 2017年 HCreater. All rights reserved.
//

#import "AFNetWorkUtils.h"
#import <AFNetworking/AFNetworking.h>
#import <AFNetworking/AFNetworkActivityIndicatorManager.h>
#import "MJExtension.h"

NSString *const netWorkUtilsDomain = @"http://AFNetWorkUtils";

NSString *const operationInfoKey = @"operationInfoKey";

NSString *const errorHelperDomain = @"http://NSErrorHelper";

@implementation NSErrorHelper

+ (NSString *)handleErrorMessage:(NSError *)error {
    NSString * result = nil;
    switch (error.code) {
        case customErrorCode://0 自定义错误
            result = error.userInfo[customErrorInfoKey];
            break;
        case kCFURLErrorTimedOut://-1001
            result = @"服务器连接超时";
            break;
        case kCFURLErrorBadServerResponse://-1011
            result = @"请求无效";
            break;
        case kCFURLErrorNotConnectedToInternet: //-1009 @"似乎已断开与互联网的连接。"
        case kCFURLErrorCannotDecodeContentData://-1016 cmcc 解析数据失败
            result = @"网络好像断开了...";
            break;
        case kCFURLErrorCannotFindHost: //-1003 @"未能找到使用指定主机名的服务器。"
            result = @"服务器内部错误";
            break;
        case kCFURLErrorNetworkConnectionLost: //-1005
            result = @"网络连接已中断";
            break;
        default:
            result = @"其他错误";
            NSLog(@"其他错误 error:%@", error);
            break;
    }
    
    return result;
}

+ (NSError *)createErrorWithErrorInfo:(NSString *)customErrorInfo {
    return [NSError errorWithDomain:errorHelperDomain code:customErrorCode userInfo:@{customErrorInfoKey : customErrorInfo}];
}

+ (NSError *)createErrorWithErrorInfo:(NSString *)customErrorInfo domain:(NSString *)domain {
    return [NSError errorWithDomain:domain code:customErrorCode userInfo:@{customErrorInfoKey : customErrorInfo}];
}

+ (NSError *)createErrorWithErrorInfo:(NSString *)customErrorInfo domain:(NSString *)domain code:(NSInteger)code {
    return [NSError errorWithDomain:domain code:code userInfo:@{customErrorInfoKey : customErrorInfo}];
}

+ (NSError *)createErrorWithDomain:(NSString *)domain code:(NSInteger)code {
    return [NSError errorWithDomain:domain code:code userInfo:nil];
}

+ (NSError *)createErrorWithUserInfo:(NSDictionary *)userInfo {
    return [NSError errorWithDomain:errorHelperDomain code:customErrorCode userInfo:userInfo];
}

+ (NSError *)createErrorWithUserInfo:(NSDictionary *)userInfo domain:(NSString *)domain {
    return [NSError errorWithDomain:domain code:customErrorCode userInfo:userInfo];
}

+ (NSError *)createErrorWithUserInfo:(NSDictionary *)userInfo domain:(NSString *)domain code:(NSInteger)code {
    return [NSError errorWithDomain:domain code:code userInfo:userInfo];
}

@end

@implementation AFNetWorkUtils

static AFNetWorkUtils *sharedAFNetWorkUtils = nil;
static dispatch_once_t pred;

+ (AFNetWorkUtils *)sharedAFNetWorkUtils {
    dispatch_once(&pred, ^{
        sharedAFNetWorkUtils = [[super allocWithZone:NULL] init];
        if ([sharedAFNetWorkUtils respondsToSelector:@selector(setUp)]) {
            [sharedAFNetWorkUtils setUp];
        }
    });
    return sharedAFNetWorkUtils;
}

+ (id)allocWithZone:(NSZone *)zone {
    return [self sharedAFNetWorkUtils];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (void)setUp
{
    self.netType = WiFiNet;
    self.netTypeString = @"WIFI";
    self.customReqHeader = [NSMutableDictionary dictionary];
}

/**
 * 创建网络请求管理类单例对象
 */
+ (AFHTTPSessionManager *)sharedHTTPOperationManager
{
    static AFHTTPSessionManager *manager = nil;
    static dispatch_once_t pred;
    dispatch_once(&pred, ^{
        manager = [AFHTTPSessionManager manager];
        manager.requestSerializer = [AFJSONRequestSerializer new];
        manager.requestSerializer.timeoutInterval = 20.f;//超时时间为20s
        [manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        NSMutableSet *acceptableContentTypes = [NSMutableSet setWithSet:manager.responseSerializer.acceptableContentTypes];
        [acceptableContentTypes addObject:@"text/plain"];
        [acceptableContentTypes addObject:@"text/html"];
        [acceptableContentTypes addObject:@"text/javascript"];
        [acceptableContentTypes addObject:@"text/json"];
        [acceptableContentTypes addObject:@"application/json"];
        manager.responseSerializer.acceptableContentTypes = acceptableContentTypes;
    });
    
    // 添加头部自定义参数
    AFNetWorkUtils* networkUtils = [AFNetWorkUtils sharedAFNetWorkUtils];
    if (networkUtils.customReqHeader != nil)
    {
        NSDictionary* customReqHeader = networkUtils.customReqHeader;
        
        for (NSString* key in [customReqHeader allKeys])
        {
            NSString* value = customReqHeader[key];
            
            [manager.requestSerializer setValue:value forHTTPHeaderField:key];
        }
    }
    
    return manager;
}

- (void)startMonitoring {
    [[self startMonitoringNet] subscribeNext:^(id x) {
    }];
}

- (RACSignal *)startMonitoringNetComplete {
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    [mgr startMonitoring];
    __weak __typeof(&*self) ws = self;
    return [[RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
        [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            switch (status) {
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    ws.netType = WiFiNet;
                    self.netType = WiFiNet;
                    self.netTypeString = @"WIFI";
                    break;
                    
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    ws.netType = OtherNet;
                    ws.netTypeString = @"2G/3G/4G";
                    break;
                    
                case AFNetworkReachabilityStatusNotReachable:
                    ws.netType = NONet;
                    ws.netTypeString = @"网络已断开";
                    break;
                    
                case AFNetworkReachabilityStatusUnknown:
                    ws.netType = NONet;
                    ws.netTypeString = @"其他情况";
                    break;
                default:
                    break;
            }
            [subscriber sendNext:ws.netTypeString];
            [subscriber sendCompleted];
        }];
        return nil;
    }] setNameWithFormat:@"<%@: %p> -startMonitoringNet", self.class, self];
}

- (RACSignal *)startMonitoringNet {
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
    [mgr startMonitoring];
    __weak __typeof(&*self) ws = self;
    return [[RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
        [mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            switch (status) {
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    ws.netType = WiFiNet;
                    self.netType = WiFiNet;
                    self.netTypeString = @"WIFI";
                    break;
                    
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    ws.netType = OtherNet;
                    ws.netTypeString = @"2G/3G/4G";
                    break;
                    
                case AFNetworkReachabilityStatusNotReachable:
                    ws.netType = NONet;
                    ws.netTypeString = @"网络已断开";
                    break;
                    
                case AFNetworkReachabilityStatusUnknown:
                    ws.netType = NONet;
                    ws.netTypeString = @"其他情况";
                    break;
                default:
                    break;
            }
            [subscriber sendNext:ws.netTypeString];
            //            [subscriber sendCompleted];
        }];
        return nil;
    }] setNameWithFormat:@"<%@: %p> -startMonitoringNet", self.class, self];
}

#pragma mark - RAC
+ (RACSignal *)racDOWNLOADWthURL:(NSString *)url savePath:(NSString*)savePath
{
    @weakify(self)
    
    NSFileManager* fileMgr = [NSFileManager defaultManager];
    
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    // 创建不存在的文件夹
    NSMutableArray* paths = [NSMutableArray arrayWithArray:[savePath componentsSeparatedByString:@"/"]];
    if (paths.count>1)
    {
        [paths removeLastObject];
        
        for (NSInteger index=0; index<paths.count; index++)
        {
            NSString* filePath = [documentsDirectory copy];
            for (NSInteger sindex=0; sindex<index+1; sindex++)
            {
                filePath = [filePath stringByAppendingPathComponent:paths[sindex]];
            }
            
            BOOL isDir = NO;
            // fileExistsAtPath 判断一个文件或目录是否有效，isDirectory判断是否一个目录
            BOOL existed = [fileMgr fileExistsAtPath:filePath isDirectory:&isDir];
            if (!(isDir && existed))
            {
                // 在Document目录下创建一个archiver目录
                [fileMgr createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
            }
        }
    }
    
    //如果文件存在则先删除
    NSString* fileSavePath = [documentsDirectory stringByAppendingPathComponent:savePath];
    BOOL isDir = NO;
    BOOL existed = [fileMgr fileExistsAtPath:fileSavePath isDirectory:&isDir];
    if (!isDir && existed)
    {
        NSError* err;
        [fileMgr removeItemAtPath:fileSavePath error:&err];
    }
    
    url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    if ([AFNetWorkUtils sharedAFNetWorkUtils].netType == NONet)
    {
        @strongify(self)
        return [self getNoNetSignal];
    }
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
    {
        @strongify(self)
        AFHTTPSessionManager *manager = [self sharedHTTPOperationManager];
        
        {//下载文件
            
            NSURLSessionDownloadTask* task = [manager downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]
                                                                     progress:^(NSProgress * _Nonnull downloadProgress)
            {
                NSLog(@"Dl value : %f", downloadProgress.fractionCompleted);
                
                [subscriber sendNext:@(downloadProgress.fractionCompleted)];
            }
                                                                  destination:^NSURL*_Nonnull(NSURL*_Nonnull targetPath,NSURLResponse*_Nonnull response)
            {
                return [NSURL fileURLWithPath:fileSavePath];
            }
                                                            completionHandler:^(NSURLResponse*_Nonnull response,NSURL*_Nullable filePath,NSError*_Nullable error)
            {
                if (error)
                {
                    [subscriber sendError:error];
                }
                else
                {
                    [subscriber sendCompleted];
                }
            }];
            
            [task resume];
        }
        
        return nil;
    }];
}

/**
 *  转换成响应式请求 可重用
 *
 *  @param url   请求地址
 *  @param params 请求参数
 *
 *  @return 带请求结果（字典）的信号
 */
+ (RACSignal *)racPOSTWthURL:(NSString *)url params:(id)params {
    
    NSLog(@"Post url : %@", url);
    
    if ([params isKindOfClass:[NSString class]])
    {
        NSLog(@"Post Params : %@", params);
    }
    else if ([params isKindOfClass:[NSDictionary class]])
    {
        NSLog(@"Post Params : %@", [params jsonStringEncoded]);
    }
    
    if ([AFNetWorkUtils sharedAFNetWorkUtils].netType == NONet) {
        return [self getNoNetSignal];
    }
    return [[RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        
        AFHTTPSessionManager *manager = [self sharedHTTPOperationManager];
        
        NSURLSessionDataTask* operation;
        
        if ([params isKindOfClass:[NSString class]])
        {
            NSString* strParams = params;
            
            NSError *requestError = nil;
            NSMutableURLRequest* request = [manager.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:url] absoluteString] parameters:nil error:&requestError];
            request.HTTPBody = [strParams dataUsingEncoding:NSUTF8StringEncoding];
            operation = [manager.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                
                if (!error)
                {
                    [self handleResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation responseObject:data];
                }
                else
                {
                    [self handleErrorResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation error:error];
                }
            }];
            [operation resume];
        }
        else if ([params isKindOfClass:[AFUploadImageShell class]])
        {
            AFUploadImageShell* shell = params;
            
            NSMutableArray* imgDatas = [NSMutableArray array];
            
            NSInteger imgCount = shell.uploadImgs.count;
            for (NSInteger index=0; index<imgCount; index++)
            {
                id obj = shell.uploadImgs[index];
                
                UIImage* currentImg = nil;
                if ([obj isKindOfClass:[UIImage class]])
                {
                    currentImg = obj;
                }
                else if ([obj isKindOfClass:[AFUploadImage class]])
                {
                    AFUploadImage* afUploadImg = obj;
                    currentImg = afUploadImg.image;
                }
                
                CGSize uImgSize = currentImg.size;
                UIImage* newUploadImg = [currentImg hyb_clipToSize:(CGSize){100, 100*uImgSize.height/uImgSize.width} isEqualScale:YES];
                NSLog(@"NewUploadImgSize : %@", NSStringFromCGSize(newUploadImg.size));
                NSData* imgData = UIImagePNGRepresentation(newUploadImg);
                
                imgDatas[imgDatas.count] = imgData;
            }
            
            // 参数
            NSMutableDictionary *parameter = [NSMutableDictionary dictionary];
            parameter = shell.params;

            operation = [manager POST:url parameters:parameter constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                
                // 添加上传图片文件
                for (NSInteger imgDataIndex=0; imgDataIndex<imgCount; imgDataIndex++)
                {
                    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                    formatter.dateFormat = @"yyyyMMddHHmmss";
                    NSString *str = [formatter stringFromDate:[NSDate date]];
                    NSString *fileName = [NSString stringWithFormat:@"%@+%d.png", str, (int)imgDataIndex];
                    
                    NSData* currentImgData = imgDatas[imgDataIndex];
                    
                    NSString* strName = @"file";
                    if ([shell.uploadImgs[imgDataIndex] isKindOfClass:[AFUploadImage class]])
                    {
                        AFUploadImage* afUploadImg = shell.uploadImgs[imgDataIndex];
                        
                        strName = HCStrFormat(@"%@-%d", afUploadImg.info[@"Name"], (int)imgDataIndex);
                    }
                    
                    [formData appendPartWithFileData:currentImgData name:strName fileName:fileName mimeType:@"image/png"];
                }
                
            } progress:^(NSProgress * _Nonnull uploadProgress) {

            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                [self handleResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation responseObject:responseObject];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [self handleErrorResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation error:error];
            }];
            
//            NSError *requestError = nil;
//            NSMutableURLRequest* request = [manager.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:url] absoluteString] parameters:nil error:&requestError];
//            request.HTTPBody = [strParams dataUsingEncoding:NSUTF8StringEncoding];
//
//#define XMGBoundary @"520it"
//#define XMGEncode(string) [string dataUsingEncoding:NSUTF8StringEncoding]
//#define XMGNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
//
//            // 设置请求头(告诉服务器,这是一个文件上传的请求)
//            [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", XMGBoundary] forHTTPHeaderField:@"Content-Type"];
//
//            // 设置请求体
//            NSMutableData *body = [NSMutableData data];
//
//            // 文件参数
//            // 分割线
//            [body appendData:XMGEncode(@"--")];
//            [body appendData:XMGEncode(XMGBoundary)];
//            [body appendData:XMGNewLine];
//
//            // 文件参数名
//            [body appendData:XMGEncode([NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"test.png\""])];
//            [body appendData:XMGNewLine];
//
//            // 文件的类型
//            [body appendData:XMGEncode([NSString stringWithFormat:@"Content-Type: image/png"])];
//            [body appendData:XMGNewLine];
//
//            // 文件数据
//            [body appendData:XMGNewLine];
//            [body appendData:imgData];
//            [body appendData:XMGNewLine];
//
//            // 结束标记
//            /*
//             --分割线--\r\n
//             */
//            [body appendData:XMGEncode(@"--")];
//            [body appendData:XMGEncode(XMGBoundary)];
//            [body appendData:XMGEncode(@"--")];
//            [body appendData:XMGNewLine];
//
//            operation = [manager.session uploadTaskWithRequest:request fromData:body completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//
//                if (!error)
//                {
//                    [self handleResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation responseObject:data];
//                }
//                else
//                {
//                    [self handleErrorResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation error:error];
//                }
//            }];
//            [operation resume];
        }
        else if ([params isKindOfClass:[NSDictionary class]])
        {
            NSDictionary* paramDic = (NSDictionary*)params;
            
            operation = [manager POST:url parameters:paramDic.allKeys.count>0?paramDic:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
                
                    NSLog(@"Find Here");
                
                //            NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
                //            [mutableHeaders setValue:@"application/x-www-form-urlencoded" forKey:@"Content-Type"];
                //
                //            NSString* strUrlEncode = @"token=AA2896635E7179075ACD76A8975A0D17&latitude=23.370308&longitude=116.706734";
                //            [formData appendPartWithHeaders:mutableHeaders body:[strUrlEncode dataUsingEncoding:NSUTF8StringEncoding]];
            } progress:^(NSProgress * _Nonnull uploadProgress) {
                
            } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                [self handleResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation responseObject:responseObject];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [self handleErrorResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation error:error];
            }];
        }
        
        return [RACDisposable disposableWithBlock:^{
            [operation cancel];
        }];
    }] setNameWithFormat:@"<%@: %p> -post2racWthURL: %@, params: %@", self.class, self, url, params];
}

+ (RACSignal *)racGETWthURL:(NSString *)url {
    return [[self racGETWthURL:url isJSON:YES] setNameWithFormat:@"<%@: %p> -get2racWthURL: %@", self.class, self, url];
}

+ (RACSignal *)racGETUNJSONWthURL:(NSString *)url {
    return [[self racGETWthURL:url isJSON:NO] setNameWithFormat:@"<%@: %p> -get2racUNJSONWthURL: %@", self.class, self, url];
}

+ (RACSignal *)racGETWthURL:(NSString *)url isJSON:(BOOL)isJSON {
    if ([AFNetWorkUtils sharedAFNetWorkUtils].netType == NONet) {
        return [self getNoNetSignal];
    }
    return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        AFHTTPSessionManager *manager = [self sharedHTTPOperationManager];
        if (!isJSON) {
            manager = [AFHTTPSessionManager manager];
            manager.responseSerializer = [AFHTTPResponseSerializer serializer];
        }
        NSURLSessionDataTask *operation = [manager GET:url parameters:nil success:^(NSURLSessionDataTask *operation, id responseObject) {
            if (!isJSON) {
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
                return;
            }
            [self handleResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation responseObject:responseObject];
        }                                        failure:^(NSURLSessionDataTask *operation, NSError *error) {
            if (!isJSON) {
                [subscriber sendNext:error];
                return;
            }
            [self handleErrorResultWithSubscriber:(id <RACSubscriber>) subscriber operation:operation error:error];
        }];
        return [RACDisposable disposableWithBlock:^{
            [operation cancel];
        }];
    }];
}

/**
 *  响应式post请求 返回处理后的结果 对象类型 可重用
 *
 *  @param url   请求地址
 *  @param params 请求参数
 *  @param clazz  字典对应的对象
 *
 *  @return 带请求结果（对象）的信号
 */
+ (RACSignal *)racPOSTWithURL:(NSString *)url params:(id)params class:(Class)clazz {
    if ([AFNetWorkUtils sharedAFNetWorkUtils].netType == NONet) {
        return [self getNoNetSignal];
    }
    //有网络
    return [[[[self racPOSTWthURL:url params:params] map:^id(id responseObject) {
        if ([responseObject isKindOfClass:[NSArray class]]) {
            return [clazz objectArrayWithKeyValuesArray:responseObject];
        } else {
            return [clazz objectWithKeyValues:responseObject];
        }
    }] replayLazily] setNameWithFormat:@"<%@: %p> -racPOSTWithURL: %@, params: %@ class: %@", self.class, self, url, params, NSStringFromClass(clazz)];
}


+ (RACSignal *)racGETWithURL:(NSString *)url class:(Class)clazz {
    if ([AFNetWorkUtils sharedAFNetWorkUtils].netType == NONet) {
        return [self getNoNetSignal];
    }
    //有网络
    return [[[[self racGETWthURL:url] map:^id(id responseObject) {
        if ([responseObject isKindOfClass:[NSArray class]]) {
            return [clazz objectArrayWithKeyValuesArray:responseObject];
        } else {
            return [clazz objectWithKeyValues:responseObject];
        }
    }] replayLazily] setNameWithFormat:@"<%@: %p> -racGETWithURL: %@,class: %@", self.class, self, url, NSStringFromClass(clazz)];
}

+ (RACSignal *)getNoNetSignal {
    return [[RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        [subscriber sendError:[NSErrorHelper createErrorWithDomain:netWorkUtilsDomain code:kCFURLErrorNotConnectedToInternet]];
        return nil;
    }] setNameWithFormat:@"<%@: %p> -getNoNetSignal", self.class, self];
}

+ (void)handleErrorResultWithSubscriber:(id <RACSubscriber>)subscriber operation:(NSURLSessionDataTask *)operation error:(NSError *)error {
    NSMutableDictionary *userInfo = [error.userInfo mutableCopy] ?: [NSMutableDictionary dictionary];
    userInfo[operationInfoKey] = operation;
    userInfo[customErrorInfoKey] = [NSErrorHelper handleErrorMessage:error];
    [subscriber sendError:[NSErrorHelper createErrorWithUserInfo:userInfo domain:netWorkUtilsDomain]];
}

+ (void)handleResultWithSubscriber:(id <RACSubscriber>)subscriber operation:(NSURLSessionDataTask *)operation responseObject:(id)responseObject {
    //在此根据自己应用的接口进行统一处理
    
    if ([responseObject isKindOfClass:[NSData class]])
    {
        NSData* responseData = responseObject;
        NSString* responseStr = [responseData utf8String];
        responseObject = [responseStr jsonValueDecoded];
        
        NSLog(@"Response : %@", responseStr);
    }
    
    //示例(测试接口)
//    NSInteger count = [[responseObject objectForKey:@"count"] integerValue];
//    if (!count) {
//        [subscriber sendNext:responseObject];
//        [subscriber sendCompleted];
//        return;
//    }
    
    //上传图片接口临时特殊判断
//    if ([responseObject[@"message"] isEqualToString:@"上传图片"])
//    {
//        [subscriber sendNext:responseObject];
//        [subscriber sendCompleted];
//
//        return;
//    }
    
    //统一格式接口
    if ([responseObject isKindOfClass:[NSArray class]])
    {
        NSDictionary* responseObjectDic = @{@"datas":responseObject};
        [subscriber sendNext:responseObjectDic];
        [subscriber sendCompleted];
    }
    else if ([responseObject isKindOfClass:[NSDictionary class]])
    {
        if ([[responseObject allKeys] containsObject:@"ExceptionType"])
        {
            NSString * errorInfo = @"服务器异常";
            errorInfo = responseObject[@"ExceptionMessage"];
            NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
            userInfo[operationInfoKey] = operation;
            userInfo[customErrorInfoKey] = errorInfo;
            NSError * error = [NSErrorHelper createErrorWithUserInfo:userInfo domain:netWorkUtilsDomain];
            [subscriber sendError:error];
        }
        else if ([[responseObject allKeys] containsObject:@"status"])
        {
            NSInteger resultCode = [responseObject[@"status"] intValue];
            
            if (resultCode == 200)
            {
                NSDictionary* callbackData = @{};
                
                //返回成功数据
                if ([responseObject[@"data"] isKindOfClass:[NSArray class]])
                {
                    callbackData = @{@"datas":responseObject[@"data"]};
                }
                else if ([responseObject[@"data"] isKindOfClass:[NSDictionary class]])
                {
                    NSDictionary* dataDic = responseObject[@"data"];
                    
                    if (dataDic.allKeys.count > 0)
                    {
                        NSMutableDictionary* newDataDic = [NSMutableDictionary dictionaryWithDictionary:dataDic];
                        newDataDic[SUCommandSysMessageKey] = responseObject[@"message"];
                        
                        callbackData = newDataDic;
                    }
                    else
                    {
                        callbackData = responseObject;
                    }
                }
                else
                {
                    NSMutableDictionary* newDataDic = [NSMutableDictionary dictionaryWithDictionary:responseObject];
                    newDataDic[SUCommandSysMessageKey] = responseObject[@"message"];
                    callbackData = newDataDic;
                }
                
                [subscriber sendNext:callbackData];
                [subscriber sendCompleted];
            }
            else
            {
                NSString * errorInfo = [responseObject[@"message"] isNotBlank] ? responseObject[@"message"] : @"服务器异常";
                NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
                userInfo[operationInfoKey] = operation;
                userInfo[customErrorInfoKey] = errorInfo;
                NSError * error = [NSErrorHelper createErrorWithUserInfo:userInfo domain:netWorkUtilsDomain];
                [subscriber sendError:error];
            }
        }
        else
        {
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
        }
    }
    
//    if ([[responseObject allKeys] containsObject:@"ExceptionType"])
//    {
//        //错误返回
//        NSInteger status = [[responseObject objectForKey:@"status"] integerValue];
//        if (status == 1) { //接口调用成功
//            //  [subscriber sendNext:RACTuplePack(operation,responseObject)];
//            [subscriber sendNext:responseObject];
//            [subscriber sendCompleted];
//        } else {//正确返回，带有错误信息
//            NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
//            userInfo[operationInfoKey] = operation;
//            BOOL isError = status == 0;
//            NSString * errorInfo = @"服务器异常";
//            if (isError)
//            {
//                if ([responseObject objectForKey:@"result"])
//                {
//                    id resultObj = [responseObject objectForKey:@"result"];
//
//                    if ([resultObj isKindOfClass:[NSDictionary class]])
//                    {
//                        NSDictionary* resultInfo = resultObj;
//
//                        if ([resultInfo objectForKey:@"text"])
//                        {
//                            errorInfo = resultInfo[@"text"];
//                        }
//                    }
//                    else if ([responseObject objectForKey:@"message"])
//                    {
//                        errorInfo = responseObject[@"message"];
//                    }
//                }
//                else if ([responseObject objectForKey:@"message"])
//                {
//                    errorInfo = responseObject[@"message"];
//                }
//            }
//
//            userInfo[customErrorInfoKey] = errorInfo;
//            NSError * error = [NSErrorHelper createErrorWithUserInfo:userInfo domain:netWorkUtilsDomain];
//            [subscriber sendError:error];
//        }
//    }
//    else
//    {
//        [subscriber sendNext:responseObject];
//        [subscriber sendCompleted];
//    }
}

@end


@implementation AFUploadImage

+ (id)createWithImage:(UIImage*)image info:(NSDictionary*)info
{
    AFUploadImage* uploadImg = [[AFUploadImage alloc] init];
    
    uploadImg.image = image;
    uploadImg.info = info;
    
    return uploadImg;
}

@end

@implementation AFUploadImageShell

+ (id)createWithImgs:(NSArray*)imgs params:(id)params
{
    AFUploadImageShell* shell = [[AFUploadImageShell alloc] init];
    
    shell.uploadImgs = imgs;
    shell.params = params;
    
    return shell;
}

+ (id)createWithImgs:(NSArray*)imgs jsonParams:(id)params
{
    AFUploadImageShell* shell = [[AFUploadImageShell alloc] init];
    
    shell.uploadImgs = imgs;
    
    if ([params isKindOfClass:[NSDictionary class]])
    {
        NSDictionary* pInfo = params;
        NSString* strPJson = [pInfo jsonStringEncoded];
        
        shell.params = @{@"json":strPJson};
    }
    else
    {
        shell.params = params;
    }
    
    return shell;
}

@end
